/**
 * @author Xin Xiao 
 * @description 
 * @version 1.0.0
 * @date 20210309
 * @copyright MIN-Group:国家重大科技基础设施-未来网络北大实验室：深圳信息论与未来网络重点实验室
 */

var SelfEncodingBase = require('../encoding/SelfEncodingBase').SelfEncodingBase
var Encoder = require('../encoding/Encoder').Encoder
var Block = require('../encoding/Block').Block
var TLV = require('../encoding/TLV')
var FieldType = require('../encoding/TLV').FieldType
var createSignatureInfoByBlock = require('./SignatureInfo').createSignatureInfoByBlock
var createSignatureValueByBlock = require('./SignatureValue').createSignatureValueByBlock
var Signature = require('./Signature').Signature

 /**
  * @description 表示一个MIN包格式中的签名区
  */
 class SignatureField extends SelfEncodingBase{
   constructor(){
     super()
     this.signatures = new Array()
   }

   /**
    * @description 添加一个签名
    * @param {Signature}
    */
   addSignature(signature){
     this.signatures.push(signature)
   }

   /**
    * @description 获取指定位置的签名
    * @param{number} index
    * @return 
    */
   getSignature(index){
     if(index > this.signatures.length){
       throw new SignatureFieldError("Out of range of sigantures")
     }
     return this.signatures[index]
   }

   /**
    * @description 获得所有签名
    * @return {[]Signaturs}
    */
   getSignatures(){
     return this.signatures
   }

    /**
   * @description 将 签名区 线速编码为 TLV
   * @param {Encoder} Encoder
   * @return {number} totalLength
   */
  wireEncode(encoder){
    //如果签名区没有签名，则可以直接去掉签名区 TLV ，因为他不是必需的
    if(this.signatures.length ==0){
      return 0
    }
		let totalLength = 0
    // 编码 TLV-VALUE
	  // 反向遍历，可以保证解码的时候正向输出
    for (let i =this.signatures.length - 1;i>=0;i--){
      if(this.signatures[i] == undefined || this.signatures[i] == null){
        continue
      }
      let signature = this.signatures[i]
      try {
        let tmpLen = signature.SigValue.wireEncode(encoder)
        totalLength += tmpLen
      } catch (error) {
        throw error
      }
      try {
        let tmpLen = signature.SigInfo.wireEncode(encoder)
        totalLength +=tmpLen
      } catch (error) {
        throw error
      }
    }

    //编码签名区 TLV-LENGTH
    try {
      let tmpLen = encoder.prependVarNumber(BigInt(totalLength))
      totalLength += tmpLen
    } catch (error) {
      throw error
    }

    //编码签名区 TLV-TYPE
    try {
      let tmpLen = encoder.prependVarNumber(FieldType.TlvSignatureField)
      totalLength += tmpLen
    } catch (error) {
      throw error
    }
    return totalLength
	}

  /**
	 * @description 从 TLV Block 中解码出一个SignatureField
	 * @param {Block} block
	 */
	wireDecode(block){
    let result
		try {
			//检查Type是否正确
			TLV.expectType(block.getType(),FieldType.TlvSignatureField)
      // 解析子组件
      block.parseSubElements()
    }catch(error){
      throw error
    }
    var subElements = block.getSubElements()
    var subElementNum = subElements.length
    if(subElementNum%2 != 0){
      throw new SignatureFieldError("Invalid SignatureField TLV, require even num sub element")
    }

    //存储所有解析到的签名
    var signatures = new Array(subElementNum/2)

    //解析每一个签名
    for(let i = 0; i < subElementNum;i += 2){
      try {
        var signatureInfo = createSignatureInfoByBlock(subElements[i])
        var signatureValue = createSignatureValueByBlock(subElements[i+1])
        //用签名信息和签名值构建一个签名 
        var signature = new Signature() 
        signature.SigInfo =signatureInfo
        signature.SigValue = signatureValue 
        signatures[i/2] = signature
      } catch (error) {
        throw error
      }
    }
    this.signatures = signatures
	}
 }

 //错误处理

 class SignatureFieldError{
   constructor(m){
     this.msg = m || ""
   }

   static error(){
     console.log("SignatureFieldError: "+ this.msg)
   }
 }

 module.exports = {
   SignatureField: SignatureField,
   SignatureFieldError: SignatureFieldError

 }